#lang scribble/doc


@(require scribble/manual)
@(require (except-in rosetta section))


@title{Rosetta}
@declare-exporting[Rosetta]


@section{Defer constructors}

Defer constructors are functions that produce geometric shapes in a
lazy fashion. This means that in fact these constructors return a node
instead of an actual shape, which when evaluated will produce the
desired shape. The shapes are evaluated by the function 'evaluate' or
'evaluate-toplevel'. However, the user does not have to worry about
this evaluation model because it happens automatically in most cases.


@subsection{Points}

@defproc*[(((point (c coord?)) node?)
           ((point (x number?) (y number?) (z number?)) node?))]{
First version: creates a point at coordinate @racket[c].

Second version: creates a point at coordinate (x,y,z).
}


@subsection{Lines}

@defproc*[(((arc (r distance?) (angle angle?)) node?)
           ((arc (c coord?) (r distance?) (angle angle?)) node?)
           ((arc (c coord?) (r distance?) (begin-angle angle?) (end-angle angle?)) node?))]{
First version: creates a circular arc centered at the origin, of angle
@racket[angle] (radians) with the X-axis, and radius @racket[r].

Second version: creates a circular arc with center @racket[c], of
angle @racket[angle] (radians) with the X-axis, and radius
@racket[r].

Third version: creates a circular arc with center @racket[c], of angle
beginning at @racket[begin-angle] (radians) with the X-axis and ending
at @racket[end-angle] (radians with the X-axis, and radius
@racket[r].
}

@defproc*[(((elliptical-arc (x-r distance?) (y-r distance?) (angle angle?)) node??)
           ((elliptical-arc (c coord?) (x-r distance?) (y-r distance?) (angle? angle?)) node?)
           ((elliptical-arc (c coord?) (x-r distance?) (y-r distance?) (begin-angle angle?) (end-angle angle?)) node?))]{
First version: creates an elliptical arc centered at the origin, of
angle @racket[angle] (radians) with the X-axis, and radius
@racket[x-r] along the X-axis and radius @racket[y-r] along the
Y-axis.

Second version: creates an elliptical arc with center @racket[c], of
angle @racket[angle] (radians) with the X-axis, and radius
@racket[x-r] along the X-axis and radius @racket[y-r] along the
Y-axis.

Third version: creates an elliptical arc with center @racket[c], of
angle beginning at @racket[begin-angle] (radians) with the X-axis and
ending at @racket[end-angle] (radians with the X-axis, and radius
@racket[x-r] along the X-axis and radius @racket[y-r] along the
Y-axis.
}

@defproc*[(((circle (r distance?)) node?)
           ((circle (c coord?) (r distance?)) node?))]{
First version: creates a circular line centered at the origin of
radius @racket[r].

Second version: creates a circular line with center @racket[c] and
radius @racket[r].
}

@defproc*[(((ellipse (x-r distance?) (y-radius distance?)) node?)
           ((ellipse (c coord?) (x-r distance?) (y-r distance?)) node?))]{
First version: creates an elliptical line centered at the origin of
radius @racket[x-radius] along the X-axis and radius @racket[y-radius]
along the Y-axis.

Second version: creates an elliptical line with center @racket[c],
radius @racket[x-r] along the X-axis and radius @racket[y-r] along the
Y-axis.
}

@defproc*[(((line (cs (listof coord?))) node?)
           ((line (c1 coord?) (c2 coord?) ...) node?))]{
First version: creates a line composed of straight line segments
passing through coordinates @racket[cs]. If the last coordinate is
equal to the first coordinate then the line is closed; otherwise the
line is open.

Second version: a convenience function for the first version.
}

@defproc*[(((line-closed (cs (listof coord?))) node?)
           ((line-closed (c1 coord?) (c2 coord?) ...) node?))]{
First version: creates a closed line composed of straight line
segments passing through coordinates @racket[cs]. The first and the
last coordinates cannot be equal.

Second version: a convenience function for the first version.
}

@defproc[(ngon (width distance?) (sides (and/c integer? positive?))) node?]{TODO}

@defproc[(nurbs-curve
          (controls (listof coord?))
          (knots (listof (and/c integer? (not/c negative?)))))
         node?]{
Creates a Non-Uniform Rational B-Spline (NURBS) curve where
@racket[controls] is a list of control coordinates and @racket[knots]
is the list of knots.
}

@defproc[(nurbs-surface
          (controls (listof coord?))
          (u-knots (listof (and/c integer? (not/c negative?))))
          (v-knots (listof (and/c integer? (not/c negative?)))))
         shape?]{
Creates a Non-Uniform Rational B-Spline (NURBS) surface where
@racket[controls] is the list of control points, @racket[u-knots] is
the list of knots in the U-direction and @racket[v-knots] is the list
of knots in the V-direction.
}

@defproc*[(((rectangle (w distance?) (l distance?)) node?)
           ((rectangle (c1 coord?) (c2 coord?)) node?)
           ((rectangle (c coord?) (w distance?) (l distance?)) node?))]{
First version: creates a rectangular line in the XY-plane, aligned
with the coordinate system, centered at the origin, width @racket[w]
along the X-axis and length @racket[l] along the Y-axis.

Second version: creates a rectangular line parallel to the XY-plane,
aligned with the coordinate system, with center halfway of @racket[c1]
and @racket[c2], where @racket[c1] and @racket[c2] are the corners of
the rectangular surface.

Third version: creates a rectangular line parallel to the XY-plane,
aligned with the coordinate system, with center @racket[c], width
@racket[w] along the X-axis and length @racket[l] along the Y-axis.
}

@defproc*[(((spline (cs (listof coord?))) node?)
           ((spline (c1 coord?) (c2 coord?) ...) node?))]{
First version: creates a spline that interpolates coordinates
@racket[cs].

Second version: a convenience function for the first version.
}

@defproc[(star (width distance?) (sides (and/c integer? positive?)) (stride (and/c integer? positive?))) node?]{TODO}


@subsection{Surfaces}

@defproc*[(((annulus (inner-radius distance?) (outer-radius distance?)) node?)
           ((annulus (c coord?) (inner-radius distance?) (outer-radius distance?)) node?))]{
First version: creates an annulus in the XY-plane, centered at the
origin, of inner radius @racket[inner-radius] and outer radius
@racket[outer-radius].

Second version: creates an annulus in the XY-plane, with center
@racket[c], inner radius @racket[inner-radius] and outer radius
@racket[outer-radius].

An annulus is the surface that results from subtracting two
concentrical circular surfaces of different radii.
}

@defproc*[(((circle-surface (r distance?)) node?)
           ((circle-surface (c coord?) (r distance?)) node?))]{
First version: creates a circular surface in the XY-plane, centered at
the origin, of radius @racket[r].

Second version: creates a circular surface in the XY-plane, with
center @racket[c] and radius @racket[r].
}

@defproc*[(((rectangle-surface (w distance?) (l distance?)) node?)
           ((rectangle-surface (c1 coord?) (c2 coord?)) node?)
           ((rectangle-surface (c coord?) (w distance?) (l distance?)) node?))]{
First version: creates a rectangular surface in the XY-plane, aligned
with the coordinate system, centered at the origin, width @racket[w]
along the X-axis and length @racket[l] along the Y-axis.

Second version: creates a rectangular surface parallel to the
XY-plane, aligned with the coordinate system, where @racket[c1] and
@racket[c2] are the corners of the rectangular surface.

Third version: creates a rectangular surface parallel to the XY-plane,
aligned with the coordinate system, with center @racket[c], width
@racket[w] along the X-axis and length @racket[l] along the Y-axis.
}

@defproc*[(((surface (closed-line node?)) node?)
           ((surface (c1 coord?) (c2 coord?) (c3 coord?)) node?)
           ((surface (s1 node?) (s2 node?) (s3 node?)) node?)
           ((surface (c1 coord?) (c2 coord?) (c3 coord?) (c4 coord?)) node?)
           ((surface (s1 node?) (s2 node?) (s3 node?) (s4 node?)) node?)
	   ((surface (cs (listof coord?))) node?))]{
First version: create a surface from closed line @racket[closed-line].

Second version: creates a surface where @racket[c1], @racket[c2] and
@racket[c3] are the corners of the surface.

Third version: creates a surface where @racket[s1], @racket[s2] and
@racket[s3] are the edges of the surfaces.

Fourth version: creates a surface where @racket[c1], @racket[c2],
@racket[c3] and @racket[c4] are the corners of the surface.

Fifth version: creates a surface where @racket[s1], @racket[s2],
@racket[s3] and @racket[s4] are the edges of the surfaces.

Sixth version: a convenience function for the previous versions.
}

@defproc[(surface (p1 point?) (p2 point?) (p3 point?) (p4 point?))
shape?]{ Creates a surface where @racket[p1], @racket[p2], @racket[p3]
and @racket[p4] are the corners of the surface.
}

 
@subsection{Solids}

@defproc*[(((box (c1 coord?) (c2 coord?)) node?)
           ((box (w distance?) (l distance?) (h distance?)) node?)
           ((box (c coord?) (w distance?) (l distance?) (h distance?)) node?))]{
First version: creates a solid parallelepiped, align with the
coordinate system, where @racket[c1] and @racket[c2] are the corners
of the solid.

Second version: creates a solid parallelepiped, aligned with the
coordinate system, centered at the origin, of width @racket[w] along
the X-axis, length @racket[l] along the Y-axis and height @racket[h]
along the Z-axis.

Third version: creates a solid parallelepiped, aligned with the
coordinate system, with center @racket[c], width @racket[w] along the
X-axis, length @racket[l] along the Y-axis and height @racket[h] along
the Z-axis.
}
                
@defproc*[(((cone (r distance?) (h distance?)) node?)
           ((cone (c coord?) (r distance?) (h distance?)) node?)
           ((cone (c1 coord?) (r distance?) (c2 coord?)) node?))]{
First version: creates a solid cone, oriented along the Z-axis, with
base centered at the origin, in the XY-plane, with radius @racket[r]
and height @racket[h].

Second version: creates a solid cone, oriented along the Z-axis, with
base centered at @racket[c], parallel to the XY-plane, with radius
@racket[r] and height @racket[h].

Third version: creates a solid cone, with base center @racket[c1],
base radius @racket[r] and apex @racket[c2].
}

@defproc*[(((cone-frustrum (r distance?) (h distance?) (top-r distance?)) node?)
           ((cone-frustrum (c coord?) (r distance?) (h distance?) (top-r distance?)) node?)
           ((cone-frustrum (c1 coord?) (r distance?) (c2 coord?) (top-r distance?)) node?))]{
First version: creates a truncated solid cone, oriented along the
Z-axis, with base centered at the origin, in the XY-plane, with bottom
base radius @racket[r], height @racket[h] and top base radius
@racket[top-r].

Second version: creates a truncated solid cone, oriented along the
Z-axis, with bottom base center @racket[c], parallel to the XY-plane,
with bottom base radius @racket[r], height @racket[h] and top base
radius @racket[top-r].

Third version: creates a truncated solid cone, with bottom base center
@racket[c1], bottom base radius @racket[r], apex @racket[c2] and top
base radius @racket[top-r].
}

@defproc*[(((cone (r distance?) (h distance?)) node?)
           ((cone (c coord?) (r distance?) (h distance?)) node?)
           ((cone (c1 coord?) (r distance?) (c2 coord?)) node?))]{
First version: creates a solid cylinder, oriented along the Z-axis,
with base centered at the origin, in the XY-plane, with radius
@racket[r] and height @racket[h].

Second version: creates a solid cylinder, oriented along the Z-axis,
with base centered at @racket[c], parallel to the XY-plane, with
radius @racket[r] and height @racket[h].

Third version: creates a solid cylinder, with bottom base center
@racket[c1], base radius @racket[r] and top base center @racket[c2].
}

@defproc*[(((sphere (r distance?)) node?)
           ((sphere (c coord?) (r distance?)) node?))]{
First version: creates a solid sphere, centered at the origin, with
radius @racket[radius].

Second version: creates a solid sphere, with center @racket[c] and
radius @racket[r].
}
                
 
@subsection{Operations}

@defproc[(extrude (length number?) (dir coord?) (node node?)) node?]{
Extrudes @racket[node] by @racket[length] along direction
@racket[dir].
}

@defproc*[(((intersect (nodes (listof node?))) node?)
           ((intersect (n1 node?) (n2 node?) ...) node?))]{
First version: intersects @racket[nodes].

Second version: a convenience function for the first version.
}

@defproc*[(((join (nodes (listof node?))) node?)
           ((join (n1 node?) (n2 node?) ...) node?))]{
First version: joins the lines specified by @racket[nodes] together to
form a single line.

Second version: a convenience function for the first version.
}

@defproc*[(((loft (nodes (listof node?))) node?)
           ((loft (n1 node?) (n2 node?) ...) node?))]{
First version: lofts @racket[nodes] smoothly.

In general, lofting lines creates surfaces and lofting surfaces
creates solids.

Second version: a convenience function for the first version.
}

@defproc*[(((loft-closed (nodes (listof node?))) node?)
           ((loft-closed (n1 node?) (n2 node?) ...) node?))]{
First version: lofts @racket[nodes] smoothly, closing the loft using
the first element of @racket[nodes].

In general, lofting lines creates surfaces and lofting surfaces
creates solids.

Second version: a convenience function for the first version.
}

@defproc*[(((loft-surface (nodes (listof node?))) node?)
           ((loft-surface (n1 node?) (n2 node?) ...) node?))]{
First version: lofts @racket[nodes] smoothly to create a surface.

Second version: a convenience function for the first version.
}

@defproc*[(((loft-surface-closed (nodes (listof node?))) node?)
           ((loft-surface-closed (n1 node?) (n2 node?) ...) node?))]{
First version: combination of @racket{loft-closed} and
@racket{loft-surface}.

Second version: a convenience function for the first version.
}

@defproc*[(((loft-solid (nodes (listof node?))) node?)
           ((loft-solid (n1 node?) (n2 node?) ...) node?))]{
First version: lofts @racket[nodes] smoothly to create a solid.

Second version: a convenience function for the first version.
}

@defproc*[(((loft-solid-closed (nodes (listof node?))) node?)
           ((loft-solid-closed (n1 node?) (n2 node?) ...) node?))]{
First version: combination of @racket{loft-closed} and
@racket{loft-solid}.

Second version: a convenience function for the first version.
}

@defproc*[(((ruled-loft (nodes (listof node?))) node?)
           ((ruled-loft (n1 node?) (n2 node?) ...) node?))]{
First version: same as @racket[loft] but ruled instead of smooth.

Second version: a convenience function for the first version.
}

@defproc*[(((ruled-loft-closed (nodes (listof node?))) node?)
           ((ruled-loft-closed (n1 node?) (n2 node?) ...) node?))]{
First version: same as @racket[loft-closed] but ruled instead of
smooth.

Second version: a convenience function for the first version.
}

@defproc*[(((ruled-loft-surface (nodes (listof node?))) node?)
           ((ruled-loft-surface (n1 node?) (n2 node?) ...) node?))]{
First version: same as @racket[loft-surface] but ruled instead
of smooth.

Second version: a convenience function for the first version.
}

@defproc*[(((ruled-loft-surface-closed (nodes (listof node?))) node?)
           ((ruled-loft-surface-closed (n1 node?) (n2 node?) ...) node?))]{
First version: same as @racket[loft-surface-closed] but ruled instead
of smooth.

Second version: a convenience function for the first version.
}

@defproc*[(((ruled-loft-solid (nodes (listof node?))) node?)
           ((ruled-loft-solid (n1 node?) (n2 node?) ...) node?))]{
First version: same as @racket[loft-solid] but ruled instead of
smooth.

Second version: a convenience function for the first version.
}

@defproc*[(((ruled-loft-solid-closed (nodes (listof node?))) node?)
           ((ruled-loft-solid-closed (n1 node?) (n2 node?) ...) node?))]{
First version: same as @racket[loft-solid-closed] but ruled instead of
smooth.

Second version: a convenience function for the first version.
}

@defproc*[(((move (c coord?) (nodes (listof node?))) node?)
           ((move (c coord?) (n1 node?) (n2 node?) ...) node?))]{
First version: applies a relative translation by @racket[c] to
@racket[nodes].

Second version: a convenience function for the first version.
}

@defproc[(offset (distance distance?) (node node?)) node?]{
Offsets @racket[node] by @racket[distance].

The sign of @racket[distance] dictates the direction of the offset.
}

@defproc*[(((rotate (angle angle?) (c coord?) (node node?)) node?)
           ((rotate (angle angle?) (c coord?) (nodes (listof node?))) node?)
           ((rotate (c1 coord?) (c2 coord?) (node node?)) node?)
           ((rotate (c1 coord?) (c2 coord?) (nodes (listof node?))) node?)
           ((rotate (angle angle?) (c coord?) (node node?) ...) node?)
           ((rotate (c1 coord?) (c2 coord?) (node node?) ...) node?))]{
First version: rotates @racket[node] by @racket[angle] radians where
@racket[c] is the normal of the rotation.

Second version: same as first version but for several @racket[nodes].

Third version: applies the rotation between @racket[c1] and
@racket[c2] to @racket[node].

Fourth version: same as third version but for several @racket[nodes].

Fifth version: a convenience function for the first and second
versions.

Sixth version: a convenience function for the third and fourth
versions.
}

@defproc*[(((rotate-x (n number?) (node node?)) node?)
           ((rotate-x (n number?) (nodes (listof node?))) node?)
           ((rotate-x (n number?) (node node?) ...) node?))]{
These are convenience functions for @racket[rotate].

Equivalent to @itemlist{@item{@racket[(rotate n ux node)]}@item{@racket[(rotate n ux nodes)]}@item{@racket[(rotate n ux node ...)]}}
}

@defproc*[(((rotate-y (n number?) (node node?)) node?)
           ((rotate-y (n number?) (nodes (listof node?))) node?)
           ((rotate-y (n number?) (node node?) ...) node?))]{
These are convenience functions for @racket[rotate].

Equivalent to @itemlist{@item{@racket[(rotate n uy node)]}@item{@racket[(rotate n uy nodes)]}@item{@racket[(rotate n uy node ...)]}}
}

@defproc*[(((rotate-z (n number?) (node node?)) node?)
           ((rotate-z (n number?) (nodes (listof node?))) node?)
           ((rotate-z (n number?) (node node?) ...) node?))]{
These are convenience functions for @racket[rotate].

Equivalent to @itemlist{@item{@racket[(rotate n uz node)]}@item{@racket[(rotate n uz nodes)]}@item{@racket[(rotate n uz node ...)]}}
}

@defproc*[(((scale (n number?) (node node?)) node?)
           ((scale (n number?) (nodes (listof node?))) node?)
           ((scale (c coord?) (node node?)) node?)
           ((scale (c coord?) (nodes (listof node?))) node?))]{
First version: scales @racket[node] by @racket[n] uniformly in all
directions.

Second version: same as first version but for several @racket[nodes].

Third version: scales @racket[node] where each component of @racket[c]
specifies the scaling factor in the X, Y and Z directions.

Fourth version: same as first version but for several @racket[nodes].
}

@defproc[(scale-center ...) node?]{TODO}

@defproc*[(((section (plane matrix?) (node node?)) node?)
           ((section (plane matrix?) (nodes (listof node?))) node?))]{
First version: sections @racket[node] in @racket[plane].

Second version: same as first version but for several @racket[nodes].

The section is the projection of a shape on a slicing plane.
}

@defproc[(section-line ...) node?]{TODO}
@defproc[(section-surface ...) node?]{TODO}

@defproc[(slice (node1 node?) (node2 node?)) node?]{
Slices @racket[node1] with @racket[node2].

Slicing cuts a shape according to another shape.
}

@defproc*[(((subtract (nodes (listof node?))) node?)
           ((subtract (n1 node?) (n2 node?) ...) node?))]{
First version: subtract @racket[nodes].

Second version: a convenience function for the first version.
}
 
@defproc[(sweep (path node?) (node node?)) node?]{
Sweeps @racket[node] along @racket[path].
}

@defproc[(thicken (distance distance?) (node node?)) node?]{TODO}

@defproc*[(((union (nodes (listof node?))) node?)
           ((union (n1 node?) (n2 node?) ...) node?))]{
First version: unites @racket[nodes].

Second version: a convenience function for the first version.
}


@subsection{Linguistic primitives}

@defproc[(align ...) node?]{TODO}

@defproc[(lift (proc procedure?) (node node?)) node?]{
Lifts @racket[proc] to a @racket[node?] monad.

Lifting allows side-effects to be evaluated at the same time as nodes.
}

@defproc*[(((on (type symbol?) (nodes (listof node?))) node?)
           ((on (type symbol?) (node node?) ...) node?))]{
First version: creates a shape for each shape in @racket[shapes] such
that the bounding boxes of the resulting shapes are aligned according
to the criteria specified by @racket[type]. The possible values of
@racket[type] are @racket['+x], @racket['-x], @racket['+y],
@racket['-y], @racket['+z], @racket['-z], @racket['right],
@racket['left], @racket['back], @racket['front], @racket['top] and
@racket['bottom]. For example, type value @racket['top], which is a
synonym for @racket['+z], applied to shapes A and B will cause shape A
to be ontop of shape B.

Second version: a convenience function for the first version.
}

@defproc[(on-right (listof shapes)) shape?]{
A convenience function for the 'on' constructor with type of value
@racket['right].
}

@defproc[(on-right (shape1 shape?) (shape2 shape?) ...) shape?]{
A convenience function for the previous constructor.
}

@defproc[(on-left (listof shapes)) shape?]{
A convenience function for the 'on' constructor with type of value
@racket['left].
}

@defproc[(on-left (shape1 shape?) (shape2 shape?) ...) shape?]{
A convenience function for the previous constructor.
}

@defproc[(on-back (listof shapes)) shape?]{
A convenience function for the 'on' constructor with type of value
@racket['back].
}

@defproc[(on-back (shape1 shape?) (shape2 shape?) ...) shape?]{
A convenience function for the previous constructor.
}

@defproc[(on-front (listof shapes)) shape?]{
A convenience function for the 'on' constructor with type of value
@racket['front].
}

@defproc[(on-front (shape1 shape?) (shape2 shape?) ...) shape?]{
A convenience function for the previous constructor.
}

@defproc[(on-top (listof shapes)) shape?]{
A convenience function for the 'on' constructor with type of value
@racket['top].
}

@defproc[(on-top (shape1 shape?) (shape2 shape?) ...) shape?]{
A convenience function for the previous constructor.
}

@defproc[(on-bottom (listof shapes)) shape?]{
A convenience function for the 'on' constructor with type of value
@racket['bottom].
}

@defproc[(on-bottom (shape1 shape?) (shape2 shape?) ...) shape?]{
A convenience function for the previous constructor.
}

@defproc*[(((sequence (nodes (listof node?))) node?)
           ((sequence (n1 node?) (n2 node?) ...) node?))]{
First version: sequences @racket[nodes].

Second version: a convenience function for the first version.

Sequencing transforms a list of nodes into a node.
}

@defproc*[(((layer (name string?) (node node?)) node?)
           ((layer (name string?) (nodes (listof node?))) node?))]{
First version: places @racket[node] in layer @racket[name].

Second version: same as first version but for several @racket[nodes].

If a layer does not exist it is automatically created.
}

@defproc*[(((auto-view
             (direction coord?)
             (projection-type projection-type?)
             (style view-style?)
             (node node?)) node?)
           ((auto-view
             (direction coord?)
             (projection-type projection-type?)
             (style view-style?)
             (nodes (listof node?))) node?))]{
First version: aligns view with @racket[direction], adapts projection
to @racket[projection-type] and style to @racket[style], making sure
that @racket[node] is visible.

Second version: same as first version but for several @racket[nodes].
}

@defproc*[(((manual-view
             (center coord?)
             (target coord?)
             (projection-type projection-type?)
             (style view-style?)
             (node node?)) node?)
           ((manual-view
             (center coord?)
             (target coord?)
             (projection-type projection-type?)
             (style view-style?)
             (nodes (listof node?))) node?))]{
First version: places camera at @racket[center] in the direction of
@racket[target], adapts projection to @racket[projection-type] and
style to @racket[style], making sure that @racket[node] is visible.

Second version: same as first version but for several @racket[nodes].

Projection type can be either @racket[ortho], @racket[(perspective)]
or @racket[(perspective lens)], where @racket[lens] specify the lens.

View style can be either @racket[realistic] or @racket[wireframe].
}

@defproc*[(((view
             (direction coord?)
             (projection-type projection-type?)
             (node node?)) node?)
           ((view
             (direction coord?)
             (projection-type projection-type?)
             (nodes (listof node?))) node?)
           ((view
             (center coord?)
             (target coord?)
             (projection-type projection-type?)
             (node node?)) node?)
           ((view
             (center coord?)
             (target coord?)
             (projection-type projection-type?)
             (nodes (listof node?))) node?))]{
First and second versions: a convenience function for
@racket[auto-view] that uses the @racket[wireframe] view style.

Third and fourth versions: a convenience function for
@racket[manual-view] that uses the @racket[wireframe] view style.
}

@defproc*[(((view-ortho-top
             (node node?)) node?)
           ((view-ortho-top
             (node (listof node?))) node?)
           ((view-ortho-top
             (center coord?)
             (node node?)) node?)
           ((view-ortho-top
             (center coord?)
             (nodes (listof node?))) node?)
           ((view-ortho-top
             (style view-style?)
             (node node?)) node?)
           ((view-ortho-top
             (style view-style?)
             (nodes (listof node?))) node?)
           ((view-ortho-top
             (center coord?)
             (style view-style?)
             (node node?)) node?)
           ((view-ortho-top
             (center coord?)
             (style view-style?)
             (nodes (listof node?))) node?))]{
First and second versions: a convenience function for
@racket[auto-view] that uses @racket[(xyz 0 0 -1)] direction,
@racket[ortho] projection type and @racket[wireframe] view style.

Third and fourth versions: a convenience function for
@racket[manual-view] that uses the origin as target and @racket[ortho]
projection type.

Fifth and sixth versions: a convenience function for
@racket[auto-view] that uses @racket[(xyz 0 0 -1)] direction and
@racket[ortho] projection type.

Seventh and eighth versions: a convenience function for
@racket[manual-view] that uses the origin as target and @racket[ortho]
as projection type.
}

@defproc*[(((view-perspective (node node?)) node?)
           ((view-perspective (nodes (listof node?))) node?))]{
First version: a convenience function for @racket[auto-view]that uses
@racket[(xyz 1 1 -1)] direction, @racket[(perspective)] projection
type and @racket[realistic] view style.
}

 
@section{Imediate Constructors}

Imediate constructors are functions that, contrary to defer constructors,
are imediately evaluated. Therefore, they act just like normal functions.


@subsection{Shapes}

@subsection{Evaluation}

@defproc[(evaluate (exp any/c)) any/c]{
If @racket[exp] is a node created and there is a backend selected then
@racket[exp] is evaluated within the selected backend and the
resulting shape is returned. Otherwise, @racket[exp] itself is
returned. This function should only be directly invoked in special
cases.
}

@defproc[(evaluate-toplevel (exp any/c)) any/c]{
Same as @racket[evaluate] however it allows for optimizations to take
place because this function is intended to be invoked at the
toplevel. This function should only be directly invoked in special
cases.
}

@defproc[(bbox (node node?)) bbox?]{
Returns the bounding box of @racket[node].
}

 
@subsection{Points}

@defproc[(point? (expr any/c)) boolean?]{
Tests whether @racket[expr] is a @racket[point?].
}

@defproc[(point-c (node node?)) coord?]{
Returns the @racket[coord?] associated with @racket[node].
}


@subsection{Lines}

@defproc[(line? (expr any/c)) boolean?]{
Tests whether @racket[expr] is a @racket[line?].
}

@defproc[(line-closed? (expr any/c)) boolean?]{
Tests whether @racket[expr] is a closed @racket[line?].
}

@defproc[(polygonal-line? (expr any/c)) boolean?]{
Tests whether @racket[expr] is a polygonal @racket[line?].

While @racket[line?] includes lines, such as, circle and rectangle
lines, @racket[polygonal-line?] includes only those lines that are
composed of straight line segments.
}

@defproc[(line-begin-c (node node?)) coord?]{
Returns the first @racket[coord?] of @racket[node].
}

@defproc[(line-cs (node node?)) (listof coord?)]{
Returns the coordinates of @racket[node].
}

@defproc[(line-end-c (node node?)) coord?]{
Returns the last @racket[coord?] of @racket[node].
}


@subsection{Surfaces}

@defproc[(surface-curvature ...) ...]{TODO}
@defproc[(surface-domain ...) ...]{TODO}


@subsection{Linguistic primitives}

@defproc[(par (shape shape?)) parametric?]{TODO}


@subsection{CAD primitives}

@defproc[(clone-shape (shape shape?)) shape?]{
Clones @racket[shape] in its owner backend.
}

@defproc[(clone-shapes (shapes (listof shape?))) (listof shape?)]{
Clones @racket[shapes] in their owner backends.
}

@defproc[(delete-shape (shape shape?)) shape?]{
Deletes @racket[shape] from its owner backend.
}

@defproc[(delete-shapes (shapes (listof shape?))) (listof shape?)]{
Clones @racket[shapes] from their owner backends.
}

@defproc[(get-shapes) (listof shape?)]{
Get all shapes from current backend.
}

@defproc[(prompt-point (message string?)) coord?]{
Asks the user to insert a point in the current backend, displaying
@racket[message].
}

@defproc[(prompt-shape (message string?)) coord?]{
Asks the user to select a shape in the current backend, displaying
@racket[message].
}

@defproc[(render-shapes (width integer?) (height integer?) (path path?) (type render-type?)) void?]{
Renders all shapes in the current backend to an image file with
@racket[width]x@racket[height] resolution, located at @racket[path]
with quality @racket[type].

Render type can be either @racket[draft] or @racket[presentation].
}

@defproc[(select-shape (shape shape?)) void?]{
Selects @racket[shape] in its owner backend.
}

@defproc[(select-shapes (shapes (listof shape?))) void?]{
Selects @racket[shapes] in their owner backends.
}

@defproc[(unselect-all-shapes) void?]{
Unselects all shapes in the current backend.
}

@defproc[(view! ...) ...]{TODO}
@defproc[(view-ortho-top! ...) ...]{TODO}
@defproc[(view-perspective! ...) ...]{TODO}


@section{High-level constructors}
 
@defproc[(arc-cs ...) shape?]{TODO}
@defproc[(arc-cs-p ...) shape?]{TODO}
@defproc[(bbox-shape ...) node?]{TODO}
@defproc[(box-center ...) shape?]{TODO}
@defproc[(box-n ...) shape?]{TODO}
@defproc[(box-p ...) shape?]{TODO}
@defproc[(box-pp ...) shape?]{TODO}
@defproc[(circle-n ...) shape?]{TODO}
@defproc[(pipe ...) shape?]{TODO}
@defproc[(pipe-center ...) shape?]{TODO}
@defproc[(move-x ...) shape?]{TODO}
@defproc[(move-y ...) shape?]{TODO}
@defproc[(move-z ...) shape?]{TODO}
@defproc[(move-xy ...) shape?]{TODO}
@defproc[(move-yz ...) shape?]{TODO}
@defproc[(move-xz ...) shape?]{TODO}
@defproc[(scale-x ...) shape?]{TODO}
@defproc[(scale-y ...) shape?]{TODO}
@defproc[(scale-z ...) shape?]{TODO}
@defproc[(mirror-x ...) shape?]{TODO}
@defproc[(mirror-y ...) shape?]{TODO}
@defproc[(mirror-z ...) shape?]{TODO}